package cn.org.xuanguang.kepler.hormos.rdb.dml.operator.insert;

import cn.org.xuanguang.kepler.hormos.rdb.dml.operator.DmlOperator;
import cn.org.xuanguang.kepler.hormos.rdb.dml.operator.OperatorParameter;
import cn.org.xuanguang.kepler.hormos.rdb.dsl.sql.DefaultBatchSqlRequest;
import cn.org.xuanguang.kepler.hormos.rdb.dsl.sql.SqlRequest;
import cn.org.xuanguang.kepler.hormos.rdb.executor.SyncSqlExecutor;
import cn.org.xuanguang.kepler.hormos.rdb.plugin.DmlSQLBuilder;

import java.util.Arrays;
import java.util.Collection;
import java.util.List;

public class InsertOperator implements DmlOperator<InsertOperatorResulet> {
    // SyncSqlExecutor用于同步执行SQL命令
    private SyncSqlExecutor syncSqlExecutor;

    // dailatype用于指定数据库类型，影响数据库操作的执行方式
    private String dailatype;
    /**
     * 入参 如果是调用value等方法，意味着是单条记录插入
     */
    private InsertOperatorParameter parameter;

    // 生成的sql对象
    private SqlRequest sqlRequest;

    /**
     * 结果
     *
     * @return
     */
    InsertOperatorResulet result = InsertOperatorResulet.of(0);

    public InsertOperator(SyncSqlExecutor syncSqlExecutor, String dailatype, InsertOperatorParameter insertOperatorParameter) {
        this.syncSqlExecutor = syncSqlExecutor;
        this.dailatype = dailatype;
        this.parameter = insertOperatorParameter;

    }

    public static InsertOperator of(SyncSqlExecutor syncSqlExecutor, String dailatype, InsertOperatorParameter insertOperatorParameter) {
        return new InsertOperator(syncSqlExecutor, dailatype, insertOperatorParameter);
    }

    public InsertOperator table(String tableName) {
        parameter.setTableName(tableName);
        return this;
    }

    /**
     * 添加需要插入的列集合。
     *
     * @param columns 要添加的列的集合，不可为null。
     * @return 返回当前InsertOperator实例，允许链式调用。
     */
    public InsertOperator columns(Collection<String> columns) {
        parameter.getColumns().addAll(columns);
        return this;
    }

    public InsertOperator columns(String... columns) {
        parameter.getColumns().addAll(Arrays.asList(columns));
        return this;
    }

    /**
     * 向InsertOperator实例添加一组值。
     * 这个方法允许通过收集对象的方式一次性添加多个值到操作符的参数中。
     *
     * @param values 需要被添加到操作符中的值的集合。集合中的元素类型为Object，允许包含任意类型的值。
     * @return 返回当前InsertOperator实例，允许链式调用。
     */
    public InsertOperator values(Collection<Object> values) {
        parameter.getValues().addAll(values);
        return this;
    }

    public InsertOperator values(Object... values) {
        parameter.getValues().addAll(Arrays.asList(values));
        return this;
    }

    public InsertOperatorParameter getOperatorParameter() {
        return this.parameter;
    }

    /**
     * 获取sql
     *
     * @return
     */
    @Override
    public SqlRequest getSql() {
        // 校验判断是否为空和null
        if(sqlRequest == null){
            insert(parameter);
        }
        return sqlRequest;
    }

    @Override
    public InsertOperatorResulet execute() {
        int added = syncSqlExecutor.update(getSql());
        result.setAdded(added);
        return result;
    }
    /**
     * 单条新增
     * @param insertOperatorParameter
     * @return
     */
    public InsertOperator insert(InsertOperatorParameter insertOperatorParameter) {
        // 获取sql
        this.sqlRequest = DmlSQLBuilder.of(dailatype).buildInsert(insertOperatorParameter);
        return this;
    }
    /**
     * 批量新增
     * @param insertOperatorParameterList
     * @return
     */
    public InsertOperator insertBatch(List<InsertOperatorParameter> insertOperatorParameterList) {
        // 组成batchrequest
        DefaultBatchSqlRequest batchSqlRequest = new DefaultBatchSqlRequest();
        insertOperatorParameterList.forEach(insertOperatorParameter -> {
            batchSqlRequest.addBatch(DmlSQLBuilder.of(dailatype).buildInsert(insertOperatorParameter));
        });
        this.sqlRequest = batchSqlRequest;
        return this;
    }
}
